package com.scuec.groupfive.service.impl;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.scuec.groupfive.dto.QuestionSubmissionDTO;
import com.scuec.groupfive.entity.*;
import com.scuec.groupfive.mapper.FavoriteMapper;
import com.scuec.groupfive.mapper.PastExamRecordMapper;
import com.scuec.groupfive.service.PastExamRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;  // 关键导入
import java.util.stream.IntStream;
@Slf4j
@Service
public class PastExamRecordServiceImpl implements PastExamRecordService {

    @Autowired
    private PastExamRecordMapper pastExamRecordMapper;

    @Override
    @Transactional
    public Long submitPastExam(Long userId, String examType, Integer examYear,
                               List<QuestionSubmissionDTO> questions) {
        // 1. 创建考试记录
        PastExam record = new PastExam();
        record.setUserId(userId);
        record.setUsername(getUsernameById(userId));
        record.setExamType(examType);
        record.setExamYear(examYear);
        record.setExamDate(new Date());
        record.setTotalQuestions(questions.size());

        // 计算得分 - 每题5分
        int correctCount = calculateCorrectAnswers(questions);
        record.setCorrectQuestions(correctCount);
        record.setScore((double) (correctCount * 5)); // 每题5分，直接乘以5
        record.setTotalTime(calculateTotalTime(questions));

        // 2. 保存考试记录
        pastExamRecordMapper.insertPastExamRecord(record);

        // 3. 保存题目记录
        saveExamQuestions(record.getRecordId(), questions);

        return record.getRecordId();
    }

    private void saveExamQuestions(Long recordId, List<QuestionSubmissionDTO> questions) {
        int sequence = 1;
        for (QuestionSubmissionDTO question : questions) {
            PastExamQuestion examQuestion = new PastExamQuestion();
            examQuestion.setRecordId(recordId);
            examQuestion.setQuestionId(question.getQuestionId());
            examQuestion.setQuestionType(question.getQuestionType());
            examQuestion.setUserAnswer(question.getUserAnswer());
            examQuestion.setIsCorrect(isAnswerCorrect(question));
            examQuestion.setSequence(sequence++);

            pastExamRecordMapper.insertPastExamQuestion(examQuestion);
        }
    }

    private int calculateCorrectAnswers(List<QuestionSubmissionDTO> questions) {
        return (int) questions.stream()
                .filter(this::isAnswerCorrect)
                .count();
    }

    private boolean isAnswerCorrect(QuestionSubmissionDTO question) {
        switch (question.getQuestionType()) {
            case "single_choice":
            case "multiple_choice":
                return checkChoiceAnswer(question);
            case "fill_in_the_blank":
                return checkFillBlankAnswer(question);
            default:
                return false; // 主观题不自动判分
        }
    }

    private boolean checkChoiceAnswer(QuestionSubmissionDTO question) {
        String correctAnswer = pastExamRecordMapper.getChoiceAnswer(question.getQuestionId());
        return correctAnswer != null &&
                correctAnswer.equalsIgnoreCase(question.getUserAnswer());
    }

    private boolean checkFillBlankAnswer(QuestionSubmissionDTO question) {
        String correctAnswer = pastExamRecordMapper.getFillBlankAnswer(question.getQuestionId());
        return correctAnswer != null &&
                correctAnswer.trim().equalsIgnoreCase(question.getUserAnswer().trim());
    }

    private double calculateScore(int correctCount, int totalQuestions) {
        return totalQuestions > 0 ? (150.0 * correctCount / totalQuestions) : 0;
    }

    private int calculateTotalTime(List<QuestionSubmissionDTO> questions) {
        return questions.size() * 120; // 假设每题2分钟
    }

    private String getUsernameById(Long userId) {
        return pastExamRecordMapper.getUsernameById(userId);
    }

    @Override
    public List<PastExam> getPastExamRecordsByUserId(Long userId, int page, int size) {
        int offset = page * size;
        return pastExamRecordMapper.getPastExamRecordsByUserId(userId, offset, size);
    }

    @Override
    public List<PastExam> searchPastExamRecords(Long userId, Date startDate, Date endDate,
                                                String keyword, int page, int size) {
        int offset = page * size;
        return pastExamRecordMapper.searchPastExamRecords(
                userId, startDate, endDate, keyword, offset, size);
    }

    @Override
    public Map<String, Object> getPastExamRecordDetail(Long recordId) {
        long startTime = System.currentTimeMillis();
        log.info("开始获取考试详情，recordId: {}", recordId);

        try {
            // 1. 参数校验
            if (recordId == null || recordId <= 0) {
                throw new IllegalArgumentException("考试记录ID不能为空且必须大于0");
            }

            // 2. 获取考试主记录
            PastExam exam = pastExamRecordMapper.getPastExamRecordById(recordId);
            log.debug("考试主记录查询结果: {}", exam);
            if (exam == null) {
                throw new RuntimeException("未找到ID为" + recordId + "的考试记录");
            }

            // 3. 获取考试题目关联记录
            List<PastExamQuestion> examQuestions = pastExamRecordMapper.getPastExamQuestionsByRecordId(recordId);
            log.debug("考试题目关联记录查询结果，数量: {}", examQuestions.size());
            if (examQuestions.isEmpty()) {
                throw new RuntimeException("考试记录ID" + recordId + "没有关联的题目");
            }

            // 4. 并行获取各类题型详情
            CompletableFuture<List<QuestionInfo>> questionInfosFuture = CompletableFuture.supplyAsync(() ->
                    safeGetQuestionInfos(recordId));

            CompletableFuture<List<ChoiceQuestion>> choiceQuestionsFuture = CompletableFuture.supplyAsync(() ->
                    pastExamRecordMapper.getChoiceQuestionsByRecordId(recordId)); // 直接获取选择题完整信息

            CompletableFuture<List<FillBlankQuestion>> fillBlankQuestionsFuture = CompletableFuture.supplyAsync(() ->
                    pastExamRecordMapper.getFillBlankQuestionsByRecordId(recordId));

            CompletableFuture<List<SubjectiveQuestion>> subjectiveQuestionsFuture = CompletableFuture.supplyAsync(() ->
                    pastExamRecordMapper.getSubjectiveQuestionsByRecordId(recordId));

            // 等待所有查询完成
            CompletableFuture.allOf(
                    questionInfosFuture,
                    choiceQuestionsFuture,
                    fillBlankQuestionsFuture,
                    subjectiveQuestionsFuture
            ).join();

            // 5. 组织返回数据
            Map<String, Object> result = new LinkedHashMap<>();
            result.put("examInfo", exam);

            // 按题型分组
            Map<String, List<PastExamQuestion>> questionsByType = examQuestions.stream()
                    .collect(Collectors.groupingBy(PastExamQuestion::getQuestionType));

            // 合并选择题数据（关键修改部分）
            result.put("choiceQuestions", mergeChoiceQuestionData(
                    questionsByType.getOrDefault("single_choice", Collections.emptyList()),
                    questionInfosFuture.get(),
                    choiceQuestionsFuture.get()
            ));

            // 合并填空题数据
            result.put("fillBlankQuestions", mergeFillBlankQuestionData(
                    questionsByType.getOrDefault("fill_in_the_blank", Collections.emptyList()),
                    questionInfosFuture.get(),
                    fillBlankQuestionsFuture.get()
            ));

            // 合并主观题数据
            result.put("subjectiveQuestions", mergeSubjectiveQuestionData(
                    questionsByType.getOrDefault("subjective", Collections.emptyList()),
                    questionInfosFuture.get(),
                    subjectiveQuestionsFuture.get()
            ));

            // 计算各题型得分
            result.put("choiceScore", calculateTypeScore(
                    questionsByType.get("single_choice"),
                    exam.getTotalQuestions()
            ));

            result.put("fillBlankScore", calculateTypeScore(
                    questionsByType.get("fill_in_the_blank"),
                    exam.getTotalQuestions()
            ));

            result.put("subjectiveScore", calculateTypeScore(
                    questionsByType.get("subjective"),
                    exam.getTotalQuestions()
            ));

            return result;
        } catch (Exception e) {
            log.error("处理考试详情失败 recordId={}", recordId, e);
            throw new RuntimeException("数据处理异常: " + e.getMessage());
        }
    }
    /**
     * 专门处理选择题数据合并
     */
    private List<Map<String, Object>> mergeChoiceQuestionData(
            List<PastExamQuestion> examQuestions,
            List<QuestionInfo> questionInfos,
            List<ChoiceQuestion> choiceQuestions) {

        if (examQuestions == null || examQuestions.isEmpty()) {
            return Collections.emptyList();
        }

        // 创建映射关系
        Map<Long, QuestionInfo> questionInfoMap = questionInfos.stream()
                .collect(Collectors.toMap(QuestionInfo::getQuestionId, Function.identity()));

        Map<Long, ChoiceQuestion> choiceQuestionMap = choiceQuestions.stream()
                .collect(Collectors.toMap(ChoiceQuestion::getQuestionId, Function.identity()));

        return examQuestions.stream().map(examQuestion -> {
            Map<String, Object> merged = new HashMap<>();

            // 基础信息
            merged.put("recordId", examQuestion.getRecordId());
            merged.put("questionId", examQuestion.getQuestionId());
            merged.put("questionType", examQuestion.getQuestionType());
            merged.put("userAnswer", examQuestion.getUserAnswer());
            merged.put("isCorrect", examQuestion.getIsCorrect());
            merged.put("sequence", examQuestion.getSequence());

            // 题目内容
            QuestionInfo questionInfo = questionInfoMap.get(examQuestion.getQuestionId());
            if (questionInfo != null) {
                merged.put("content", questionInfo.getContent());
                merged.put("difficulty", questionInfo.getDifficulty());
            }

            // 选择题特有信息（关键修改部分）
            ChoiceQuestion choiceQuestion = choiceQuestionMap.get(examQuestion.getQuestionId());
            if (choiceQuestion != null) {
                merged.put("options", choiceQuestion.getOptions()); // 确保这里获取到选项
                merged.put("correctAnswer", choiceQuestion.getAnswer()); // 正确答案
                merged.put("analysis", choiceQuestion.getAnalysis()); // 解析
            }

            return merged;
        }).collect(Collectors.toList());
    }
    /**
     * 填空题数据合并（完整实现）
     * @param examQuestions 考试题目关联记录
     * @param questionInfos 题目基本信息
     * @param fillBlankQuestions 填空题详细信息
     * @return 合并后的填空题数据列表
     */
    private List<Map<String, Object>> mergeFillBlankQuestionData(
            List<PastExamQuestion> examQuestions,
            List<QuestionInfo> questionInfos,
            List<FillBlankQuestion> fillBlankQuestions) {

        // 1. 参数防御性检查
        if (examQuestions == null || examQuestions.isEmpty()) {
            log.warn("合并填空题数据：传入的考试题目列表为空");
            return Collections.emptyList();
        }

        // 2. 创建快速查询的映射关系
        Map<Long, QuestionInfo> questionInfoMap = Optional.ofNullable(questionInfos)
                .orElseGet(Collections::emptyList)
                .stream()
                .filter(Objects::nonNull)
                .collect(Collectors.toMap(
                        QuestionInfo::getQuestionId,
                        Function.identity(),
                        (existing, replacement) -> existing));

        Map<Long, FillBlankQuestion> fillBlankQuestionMap = Optional.ofNullable(fillBlankQuestions)
                .orElseGet(Collections::emptyList)
                .stream()
                .filter(Objects::nonNull)
                .collect(Collectors.toMap(
                        FillBlankQuestion::getQuestionId,
                        Function.identity(),
                        (existing, replacement) -> existing));

        // 3. 合并数据
        return examQuestions.stream()
                .filter(Objects::nonNull)
                .map(examQuestion -> {
                    Map<String, Object> mergedData = new LinkedHashMap<>();

                    // 3.1 基础考试记录信息
                    mergedData.put("recordId", examQuestion.getRecordId());
                    mergedData.put("questionId", examQuestion.getQuestionId());
                    mergedData.put("questionType", examQuestion.getQuestionType());
                    mergedData.put("userAnswer",
                            Optional.ofNullable(examQuestion.getUserAnswer()).orElse("未作答"));
                    mergedData.put("isCorrect", examQuestion.getIsCorrect());
                    mergedData.put("sequence", examQuestion.getSequence());

                    // 3.2 题目基本信息
                    QuestionInfo info = questionInfoMap.get(examQuestion.getQuestionId());
                    if (info != null) {
                        mergedData.put("content", info.getContent());
                        mergedData.put("difficulty", info.getDifficulty());
                    } else {
                        log.warn("填空题基本信息缺失，questionId: {}", examQuestion.getQuestionId());
                        mergedData.put("content", "题目内容加载失败");
                    }

                    // 3.3 填空题特有信息处理
                    FillBlankQuestion fillBlank = fillBlankQuestionMap.get(examQuestion.getQuestionId());
                    if (fillBlank != null) {
                        // 处理填空题的blanks字段（JSON数组）
                        try {
                            Object blanks = fillBlank.getBlanks();
                            if (blanks instanceof String) {
                                mergedData.put("blanks", new ObjectMapper().readValue((String) blanks, List.class));
                            } else {
                                mergedData.put("blanks", blanks);
                            }
                        } catch (Exception e) {
                            log.error("解析填空题空白数据失败，questionId: {}", examQuestion.getQuestionId(), e);
                            mergedData.put("blanks", Collections.singletonList("空白解析失败"));
                        }

                        mergedData.put("correctAnswer",
                                Optional.ofNullable(fillBlank.getAnswerTemplate()).orElse("暂无标准答案"));
                        mergedData.put("analysis",
                                Optional.ofNullable(fillBlank.getAnalysis()).orElse("暂无解析"));
                    } else {
                        log.warn("填空题详情数据缺失，questionId: {}", examQuestion.getQuestionId());
                        mergedData.put("blanks", Collections.emptyList());
                        mergedData.put("correctAnswer", "数据加载失败");
                    }

                    return mergedData;
                })
                .collect(Collectors.toList());
    }

    /**
     * 主观题数据合并（完整实现）
     * @param examQuestions 考试题目关联记录
     * @param questionInfos 题目基本信息
     * @param subjectiveQuestions 主观题详细信息
     * @return 合并后的主观题数据列表
     */
    private List<Map<String, Object>> mergeSubjectiveQuestionData(
            List<PastExamQuestion> examQuestions,
            List<QuestionInfo> questionInfos,
            List<SubjectiveQuestion> subjectiveQuestions) {

        // 1. 参数防御性检查
        if (examQuestions == null || examQuestions.isEmpty()) {
            log.warn("合并主观题数据：传入的考试题目列表为空");
            return Collections.emptyList();
        }

        // 2. 创建快速查询的映射关系
        Map<Long, QuestionInfo> questionInfoMap = Optional.ofNullable(questionInfos)
                .orElseGet(Collections::emptyList)
                .stream()
                .filter(Objects::nonNull)
                .collect(Collectors.toMap(
                        QuestionInfo::getQuestionId,
                        Function.identity(),
                        (existing, replacement) -> existing));

        Map<Long, SubjectiveQuestion> subjectiveQuestionMap = Optional.ofNullable(subjectiveQuestions)
                .orElseGet(Collections::emptyList)
                .stream()
                .filter(Objects::nonNull)
                .collect(Collectors.toMap(
                        SubjectiveQuestion::getQuestionId,
                        Function.identity(),
                        (existing, replacement) -> existing));

        // 3. 合并数据
        return examQuestions.stream()
                .filter(Objects::nonNull)
                .map(examQuestion -> {
                    Map<String, Object> mergedData = new LinkedHashMap<>();

                    // 3.1 基础考试记录信息
                    mergedData.put("recordId", examQuestion.getRecordId());
                    mergedData.put("questionId", examQuestion.getQuestionId());
                    mergedData.put("questionType", examQuestion.getQuestionType());
                    mergedData.put("userAnswer",
                            Optional.ofNullable(examQuestion.getUserAnswer()).orElse("未作答"));
                    mergedData.put("isCorrect", examQuestion.getIsCorrect()); // 主观题可能为null
                    mergedData.put("sequence", examQuestion.getSequence());

                    // 3.2 题目基本信息
                    QuestionInfo info = questionInfoMap.get(examQuestion.getQuestionId());
                    if (info != null) {
                        mergedData.put("content", info.getContent());
                        mergedData.put("difficulty", info.getDifficulty());
                    } else {
                        log.warn("主观题基本信息缺失，questionId: {}", examQuestion.getQuestionId());
                        mergedData.put("content", "题目内容加载失败");
                    }

                    // 3.3 主观题特有信息处理
                    SubjectiveQuestion subjective = subjectiveQuestionMap.get(examQuestion.getQuestionId());
                    if (subjective != null) {
                        mergedData.put("referenceAnswer",
                                Optional.ofNullable(subjective.getReferenceAnswer()).orElse("暂无参考答案"));
                        mergedData.put("answerHints",
                                Optional.ofNullable(subjective.getAnswerHints()).orElse("暂无解题提示"));
                        mergedData.put("analysis",
                                Optional.ofNullable(subjective.getAnalysis()).orElse("暂无详细解析"));
                    } else {
                        log.warn("主观题详情数据缺失，questionId: {}", examQuestion.getQuestionId());
                        mergedData.put("referenceAnswer", "数据加载失败");
                    }

                    return mergedData;
                })
                .collect(Collectors.toList());
    }


    // 安全获取题目基本信息
    private List<QuestionInfo> safeGetQuestionInfos(Long recordId) {
        try {
            List<QuestionInfo> list = pastExamRecordMapper.getQuestionsByRecordId(recordId);
            return list != null ? list : Collections.emptyList();
        } catch (Exception e) {
            log.warn("获取题目基本信息异常", e);
            return Collections.emptyList();
        }
    }

    // 安全获取选择题
    private List<ChoiceQuestion> safeGetChoiceQuestions(Long recordId) {
        try {
            List<ChoiceQuestion> list = pastExamRecordMapper.getChoiceQuestionsByRecordId(recordId);
            return list != null ? list : Collections.emptyList();
        } catch (Exception e) {
            log.warn("获取选择题异常", e);
            return Collections.emptyList();
        }
    }

    // 安全获取填空题
    private List<FillBlankQuestion> safeGetFillBlankQuestions(Long recordId) {
        try {
            List<FillBlankQuestion> list = pastExamRecordMapper.getFillBlankQuestionsByRecordId(recordId);
            return list != null ? list : Collections.emptyList();
        } catch (Exception e) {
            log.warn("获取填空题异常", e);
            return Collections.emptyList();
        }
    }

    // 安全获取主观题
    private List<SubjectiveQuestion> safeGetSubjectiveQuestions(Long recordId) {
        try {
            List<SubjectiveQuestion> list = pastExamRecordMapper.getSubjectiveQuestionsByRecordId(recordId);
            return list != null ? list : Collections.emptyList();
        } catch (Exception e) {
            log.warn("获取主观题异常", e);
            return Collections.emptyList();
        }
    }


    /**
     * 安全计算题型得分（修复NPE问题）
     * @param questions 题目列表（可能为null或包含null元素）
     * @param totalQuestions 总题数（必须大于0）
     * @return 该题型得分（默认返回0.0）
     */
    private double calculateTypeScore(List<PastExamQuestion> questions, Integer totalQuestions) {
        // 1. 参数校验
        if (questions == null || questions.isEmpty()) {
            log.warn("无效的得分计算参数: questions={}", questions != null ? questions.size() : "null");
            return 0.0;
        }

        // 2. 安全统计正确题数
        long correctCount = Optional.ofNullable(questions)
                .orElseGet(Collections::emptyList)
                .stream()
                .filter(Objects::nonNull)
                .filter(q -> Boolean.TRUE.equals(q.getIsCorrect()))
                .count();

        // 3. 计算得分 - 每题5分
        return 5.0 * correctCount; // 使用5.0确保结果是double类型
    }

    // 辅助方法：对象转Map
    private Map<String, Object> objectToMap(Object obj) {
        return new ObjectMapper().convertValue(obj, new TypeReference<Map<String, Object>>() {});
    }
    // 合并题目数据
    /**
     * 合并题目数据
     */
    private List<Map<String, Object>> mergeQuestionData(
            List<PastExamQuestion> examQuestions,
            List<QuestionInfo> questionInfos,
            List<?> specificQuestions) {

        if (examQuestions == null || examQuestions.isEmpty()) {
            return Collections.emptyList();
        }

        // 创建题目ID到具体题目的映射
        Map<Long, Object> specificQuestionMap = specificQuestions.stream()
                .filter(Objects::nonNull)
                .collect(Collectors.toMap(
                        q -> {
                            if (q instanceof ChoiceQuestion) {
                                return ((ChoiceQuestion) q).getQuestionId();
                            } else if (q instanceof FillBlankQuestion) {
                                return ((FillBlankQuestion) q).getQuestionId();
                            } else if (q instanceof SubjectiveQuestion) {
                                return ((SubjectiveQuestion) q).getQuestionId();
                            }
                            return 0L;
                        },
                        Function.identity(),
                        (existing, replacement) -> existing // 处理重复键
                ));

        // 创建题目ID到题目信息的映射
        Map<Long, QuestionInfo> questionInfoMap = questionInfos.stream()
                .filter(Objects::nonNull)
                .collect(Collectors.toMap(
                        QuestionInfo::getQuestionId,
                        Function.identity(),
                        (existing, replacement) -> existing
                ));

        // 合并数据
        return examQuestions.stream()
                .filter(Objects::nonNull)
                .map(examQuestion -> {
                    Map<String, Object> mergedQuestion = new HashMap<>();

                    // 添加考试题目记录信息
                    mergedQuestion.put("recordId", examQuestion.getRecordId());
                    mergedQuestion.put("questionId", examQuestion.getQuestionId());
                    mergedQuestion.put("questionType", examQuestion.getQuestionType());
                    mergedQuestion.put("userAnswer", examQuestion.getUserAnswer());
                    mergedQuestion.put("isCorrect", examQuestion.getIsCorrect());
                    mergedQuestion.put("sequence", examQuestion.getSequence());

                    // 添加题目基本信息
                    QuestionInfo questionInfo = questionInfoMap.get(examQuestion.getQuestionId());
                    if (questionInfo != null) {
                        mergedQuestion.put("content", questionInfo.getContent());
                        mergedQuestion.put("difficulty", questionInfo.getDifficulty());
                        // 从数据库获取正确答案
                        String correctAnswer = pastExamRecordMapper.getCorrectAnswer(examQuestion.getQuestionId());
                        mergedQuestion.put("correctAnswer", correctAnswer != null ? correctAnswer : "暂无答案");
                    }

                    // 添加具体题型信息
                    Object specificQuestion = specificQuestionMap.get(examQuestion.getQuestionId());
                    if (specificQuestion != null) {
                        if (specificQuestion instanceof ChoiceQuestion) {
                            ChoiceQuestion cq = (ChoiceQuestion) specificQuestion;
                            mergedQuestion.put("options", cq.getOptions());
                            mergedQuestion.put("analysis", cq.getAnalysis());
                        } else if (specificQuestion instanceof FillBlankQuestion) {
                            FillBlankQuestion fq = (FillBlankQuestion) specificQuestion;
                            mergedQuestion.put("blanks", fq.getBlanks());
                            mergedQuestion.put("analysis", fq.getAnalysis());
                        } else if (specificQuestion instanceof SubjectiveQuestion) {
                            SubjectiveQuestion sq = (SubjectiveQuestion) specificQuestion;
                            mergedQuestion.put("referenceAnswer", sq.getReferenceAnswer());
                            mergedQuestion.put("analysis", sq.getAnalysis());
                        }
                    }

                    return mergedQuestion;
                })
                .collect(Collectors.toList());
    }
    // PastExamRecordServiceImpl.java
// 在类中添加：
    @Autowired
    private FavoriteMapper favoriteMapper;

    @Override
    @Transactional
    public void toggleFavorite(Long userId, Long questionId, Boolean isFavorite) {
        int status = isFavorite ? 1 : 0;
        favoriteMapper.upsertFavorite(userId, questionId, status);
    }

}